<template>
  <el-col :xs="Number(item.xs || 24)" :sm="Number(item.sm || 24)" :md="Number(item.md || 24)" :lg="Number(item.lg || 24)" :xl="Number(item.xl || 24)" v-show="!item.hide">
    <div v-if="item.type == 'recycle'">
      <el-button type="primary" @click="addRecycleFn(item)" style="margin-bottom: 10px">新增</el-button>
      <div v-for="(itey, indey) in itemValue" :key="itey" class="flex">
        <div>
          <el-form-item v-for="(itez, indez) in item.formItem" v-bind="getFormItemPropFn(item, itemKey + '.' + indey + '.' + itez.prop)" :key="indez">
            <slot name="recycleName" :item="item" :key="itemKey" :itey="itey" :itez="itez" :indey="indey" :indez="indez"></slot>
          </el-form-item>
        </div>
        <el-popconfirm @click="deleteRecycleFn(indey, itey)" title="确认删除吗?">
          <template #reference>
            <el-button type="danger" v-if="item.canDeleteFirst ? true : indey != 0">删除</el-button>
            <div v-else></div>
          </template>
        </el-popconfirm>
      </div>
    </div>
    <el-form-item v-else v-bind="getFormItemPropFn(item, itemKey)">
      <div v-if="item.tip" class="formItemTip">{{ item.tip }}</div>
      <el-input v-bind="getProp()" @input="emitHasChange" v-model="itemValue" v-if="item.type == 'input' || item.type == 'textarea' || item.type == 'number'" />
      <el-select v-bind="getProp()" @change="emitHasChange" v-model="itemValue" v-else-if="item.type == 'select' || item.type == 'selectRemote' || item.type == 'selectCreate'">
        <el-option v-for="s in item.values" :key="item.nolabel ? s : s[item.aid || 'id']" :label="item.nolabel ? s : s[item.name || 'name']" :value="item.nolabel ? s : s[item.aid || 'id']"> </el-option>
      </el-select>
      <el-checkbox-group v-bind="getProp()" @change="emitHasChange" v-model="itemValue" v-else-if="item.type == 'checkbox'">
        <el-checkbox-button :label="item.nolabel ? c : c[item.aid || 'id']" v-for="(c, i) in item.values" :key="`CHECK_${i}`">
          {{ item.nolabel ? c : c[item.name || "name"] }}
        </el-checkbox-button>
      </el-checkbox-group>
      <el-radio-group v-bind="getProp()" v-model="itemValue" @change="emitHasChange" v-else-if="item.type == 'radio'">
        <el-radio-button :label="item.nolabel ? r : r[item.aid || 'id']" v-for="(r, i) in item.values" :key="'r' + i">
          {{ item.nolabel ? r : r[item.name || "name"] }}
        </el-radio-button>
      </el-radio-group>
      <el-tree v-bind="getProp()" ref="elTreeRef" v-else-if="item.type == 'tree'" :default-checked-keys="defaultCheckedKeys" @check="handleCheckChange" />
      <el-tree-select v-bind="getProp()" @change="emitHasChange" v-model="itemValue" v-else-if="item.type == 'treeSelect'"> </el-tree-select>
      <el-date-picker v-bind="getProp() as IFormItemPItemDate" @change="emitHasChange" v-model="itemValue" v-else-if="item.type == 'daterange' || item.type == 'datetimerange' || item.type == 'monthrange' || item.type == 'date' || item.type == 'datetime'" />
      <el-time-picker v-bind="getProp()" @change="emitHasChange" v-model="itemValue" v-else-if="item.type == 'time_picker'" />
      <el-time-select v-bind="getProp()" @change="emitHasChange" v-model="itemValue" v-else-if="item.type == 'time'" />
      <el-cascader v-bind="getProp()" @change="emitHasChange" v-else-if="item.type == 'cascader'" />
      <HfwangEditor ref="wangEditorRef" @emitGetEditorValue="emitHasChange" v-else-if="item.type == 'editor'" />
      <HfUpload ref="cuploadFileRef" v-bind="getProp() as IUploadP" @emitDownTemplate="emit('emitDownTemplate', { item })" @emitBeforeUpload="emitBeforeUpload" @emitGetFile="emitGetFile" v-else-if="fileType.includes(item.type as IUploadPType)" />
      <div v-else-if="item.type == 'text'">{{ itemValue }}</div>
      <img width="120" v-else-if="item.type == 'img'" :src="itemValue" alt="" />
      <slot name="otherItem" :item="item" :key="itemKey"></slot>
    </el-form-item>
  </el-col>
</template>
<script setup lang="ts">
import type { IFormItemP } from "../../../index";
import { formEmit } from "@/components/HfForm/form";
import type { UploadRawFile } from "element-plus";
import { getModulePropFn, getFormItemPropFn } from "./form-item";
import { fileType } from "@/components/HfUpload/upload";

const props = withDefaults(defineProps<IFormItemP>(), {});
const emit = defineEmits([...formEmit, "update:modelValue"]);
defineOptions({ name: "FormItem" });
const elTreeRef = ref();
const itemValue = computed({
  get() {
    return props.modelValue;
  },
  set(value) {
    emit("update:modelValue", value);
  }
});
const defaultCheckedKeys = ref([54]);
const remoting = ref(false);
function getProp() {
  return getModulePropFn({ props, emit, remoting: remoting.value });
}
const cuploadFileRef = ref<IUploadEx>();
const wangEditorRef = ref();
const emitGetFile = ({ e }: { e: any }) => {
  let item = props.item as IUploadPItem;
  if (item.otherGetFile || item.type === "uGetExcelData") return emit("emitOtherGetFile", { e, props });
  if (item.type === "uImg") return emit("emitHasChange", { key: props.itemKey, e });
  let list = e.map((ite: any) => {
    return ite.name ? { url: ite.response.data[0] } : ite;
  });
  emit("emitHasChange", { key: props.itemKey, e: JSON.stringify(list) });
};
const refreshItemsFn = async () => {
  let item = props.item;
  if ((item.type !== "radio" && item.type !== "select" && item.type !== "checkbox" && item.type !== "treeSelect" && item.type !== "tree") || !item.url) return;
  let res = await hfoRequest.get<any>({ url: item.url, params: item.params });
  if (!res) return;
  let arr: { label: string; text: string }[] = [];
  if (item.valueType == "Object") {
    for (var k in res.data) {
      arr.push({ label: k, text: res.data[k] });
    }
  } else {
    arr = arr.concat(res.data);
  }
  if (item.values) arr = [item.values, ...arr];
  emit("emitChangeProps", { e: arr, propsName: ["formOpt", "items", props.itemKey, "values"] });
};
const initFileFnh = (e: any) => {
  let item = props.item as IUploadPItem;
  if (item.otherGetFile || item.type === "uGetExcelData" || !cuploadFileRef.value) return;
  if (item.type === "uImg") {
    cuploadFileRef.value.fileUrl = e;
    return;
  }
  itemValue.value = cuploadFileRef.value.fileList = e?.constructor == Array ? e : JSON.parse(e || "[]");
};
function handleSelectFnh(e: [] | string) {
  let item = props.item as IFormItemPItemSelect;
  if (typeof e == "object" || !item.multiple) return e;
  if (e.includes("[") && itemValue.value.includes("]")) return JSON.parse(e);
  return e.split(",");
}
const initFormItemFn = (e: any) => {
  let item = props.item;
  if (item.type == "tree") {
    nextTick(() => {
      defaultCheckedKeys.value = itemValue.value;
    });
  }
  if (item.hide) return;
  if (fileType.includes(item.type as IUploadPType)) return initFileFnh(e);
  if (["selectRemote", "selectCreate", "select"].includes(item.type) && e) return (itemValue.value = handleSelectFnh(e));
  if (item.type == "editor") return wangEditorRef.value.setHtml(e || "");
};
const emitHasChange = (e: any) => {
  emit("emitHasChange", { e, id: props.id, key: props.itemKey, item: props.item });
};
const emitBeforeUpload = ({ file }: { file: UploadRawFile }) => {
  emit("emitBeforeUpload", { file, item: props.item, itemKey: props.itemKey });
};
function addRecycleFn(item: IFormItemPItemRecycle) {
  if (!itemValue.value) itemValue.value = [];
  itemValue.value.push({ ...item.formItemPushValue });
}
function deleteRecycleFn(indey: number, itey: any) {
  itemValue.value.splice(indey, 1);
  emit("emitDeleteValue", { key: props.itemKey, indey, itey });
}
refreshItemsFn();
function handleCheckChange() {
  itemValue.value = [...elTreeRef.value.getHalfCheckedKeys(), ...elTreeRef.value.getCheckedKeys()];
}
const formItemExpose: IFormItemEx = {
  initFormItemFn,
  itemKey: props.itemKey,
  elTreeRef
};
defineExpose({ ...formItemExpose });
</script>
<style lang="scss" scoped></style>
